package com.xenione.digit;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Eugeni on 16/10/2016.
 */
public class TabDigit {

    /*
     * false: rotate upwards
     * true: rotate downwards
     */
    private boolean mReverseRotation = false;

    private TabDigitEntity mTopTab;

    private TabDigitEntity mBottomTab;

    private TabDigitEntity mMiddleTab;

    private List<TabDigitEntity> tabs = new ArrayList<>(3);

    private AbstractTabAnimation tabAnimation;

    private Matrix mProjectionMatrix = new Matrix();

    private int mCornerSize;

    private Paint mNumberPaint;

    private Paint mDividerPaint;

    private Paint mBackgroundPaint;

    private Rect mTextMeasured = new Rect();

    private int mPadding = 0;

    private String currentChar,nextChar;

    private int width,hight;

    private boolean charDrawCenter;

    private TabConfig tabConfig;

    public TabDigit(String currentChar, String nextChar,boolean mReverseRotation) {
        this(currentChar,nextChar,mReverseRotation,false);
    }

    public TabDigit(String currentChar, String nextChar,boolean mReverseRotation,boolean charDrawCenter) {
        this(currentChar,nextChar,mReverseRotation,charDrawCenter,new TabConfig(false,Color.BLACK,Color.BLACK,3,AbstractTabAnimation.DEFAULT_ELAPSED_TIME));
    }

    public TabDigit(String currentChar, String nextChar,boolean mReverseRotation,boolean charDrawCenter,TabConfig tabConfig) {
        this.mReverseRotation = mReverseRotation;
        this.charDrawCenter=charDrawCenter;
        this.tabConfig=tabConfig;
        init(currentChar,nextChar);
    }

    public void init(String currentChar, String nextChar) {

        this.currentChar=currentChar;
        this.nextChar=nextChar;

        initPaints();

        mPadding = 0;

        mCornerSize = 10;

        initTabs();
    }

    private void initPaints() {
        mNumberPaint = new Paint();
        mNumberPaint.setAntiAlias(true);
        mNumberPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mNumberPaint.setColor(Color.BLACK);

        mDividerPaint = new Paint();
        mDividerPaint.setAntiAlias(true);
        mDividerPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mDividerPaint.setColor(tabConfig.getCharBackgroundBorderDividerColor());
        mDividerPaint.setStrokeWidth(tabConfig.getCharBackgroundBorderDividerWidth());

        mBackgroundPaint = new Paint();
        mBackgroundPaint.setAntiAlias(true);
        mBackgroundPaint.setColor(tabConfig.getCharBackgroundBorderColor());
    }

    private void initTabs() {
        // top Tab
        mTopTab = new TabDigitEntity(currentChar,nextChar,mProjectionMatrix,mCornerSize,charDrawCenter);
        mTopTab.rotate(180);
        tabs.add(mTopTab);

        // bottom Tab
        mBottomTab = new TabDigitEntity(currentChar,nextChar,mProjectionMatrix,mCornerSize,charDrawCenter);
        tabs.add(mBottomTab);

        // middle Tab
        mMiddleTab = new TabDigitEntity(currentChar,nextChar,mProjectionMatrix,mCornerSize,charDrawCenter);
        tabs.add(mMiddleTab);

        tabAnimation = mReverseRotation ? new TabAnimationDown(mTopTab, mBottomTab, mMiddleTab) : new TabAnimationUp(mTopTab, mBottomTab, mMiddleTab);

        tabAnimation.initMiddleTab();

        tabAnimation.setmElapsedTime(tabConfig.getmElapsedTime());

        setInternalChar(currentChar);
    }

    public void setmNumberPaint(Paint mNumberPaint){
        this.mNumberPaint=mNumberPaint;
        calculateTextMeasured();
    }

    public void calculateTextMeasured(){
        calculateTextSize(mTextMeasured);
        width=mTextMeasured.width();
        hight=mTextMeasured.height();
        setupProjectionMatrix();
        measureTabs(width,hight);
    }

    private void setInternalChar(String internalChar) {
        for (TabDigitEntity tab : tabs) {
            tab.setChar(internalChar);
        }
    }

    private void setupProjectionMatrix() {
        mProjectionMatrix.reset();
        int centerY = hight / 2;
        int centerX = width / 2;
        MatrixHelper.translate(mProjectionMatrix, centerX, -centerY, 0);
    }

    private void measureTabs(int width, int height) {
        for (TabDigitEntity tab : tabs) {
            tab.measure(width, height);
        }
    }

    private void drawTabs(Canvas canvas) {
        for (TabDigitEntity tab : tabs) {
            tab.draw(canvas,mTextMeasured,mNumberPaint,tabConfig.getCharBackgroundBorder()?mBackgroundPaint:null,(int)mDividerPaint.getStrokeWidth());
        }
    }

    private void drawDivider(Canvas canvas) {
        canvas.save();
        canvas.concat(mProjectionMatrix);
        //canvas.drawLine(-canvas.getWidth() / 2, 0, canvas.getWidth() / 2, 0, mDividerPaint);
        //canvas.drawLine(-width / 2, 0, width / 2, 0, mDividerPaint);
        canvas.drawLine(-width / 2+mDividerPaint.getStrokeWidth(), 0, width / 2-mDividerPaint.getStrokeWidth(), 0, mDividerPaint);
        canvas.restore();
    }

    private void calculateTextSize(Rect rect) {
        mNumberPaint.getTextBounds("8", 0, 1, rect);
        //System.out.println("rect left:"+rect.left+"\ttop:"+rect.top+"\tright:"+rect.right+"\t bottom:"+rect.bottom);
        int width=getCharWidth("8",mNumberPaint);
        int hight=(int)getFontHeight(mNumberPaint);
        int left=rect.left-(width-rect.width())/2;
        int right=rect.right+(width-rect.width())/2;
        int top=rect.top-(hight-rect.height())/2;
        int bottom=rect.bottom+(hight-rect.height())/2;
        rect.set(left,top,right,bottom);
    }

    public void setTextSize(int size) {
        mNumberPaint.setTextSize(size);
    }

    public int getTextSize() {
        return (int) mNumberPaint.getTextSize();
    }

    public void setPadding(int padding) {
        mPadding = padding;
    }

    public void setDividerColor(int color) {
        mDividerPaint.setColor(color);
    }

    public int getPadding(){
        return mPadding;
    }

    public void setTextColor(int color) {
        mNumberPaint.setColor(color);
    }

    public int getTextColor() {
        return mNumberPaint.getColor();
    }

    public void setCornerSize(int cornerSize) {
        mCornerSize = cornerSize;
    }

    public int getCornerSize() {
        return mCornerSize;
    }

    public void setBackgroundColor(int color) {
        mBackgroundPaint.setColor(color);
    }

    public int getBackgroundColor() {
        return mBackgroundPaint.getColor();
    }

    public void start() {
        tabAnimation.start();
    }

    public void onDraw(Canvas canvas) {
        drawTabs(canvas);
        if(tabConfig.getCharBackgroundBorder())
           drawDivider(canvas);
    }

    public void run() {
        tabAnimation.run();
    }

    public void sync() {
        tabAnimation.sync();
    }

    public boolean isRunning(){
        return tabAnimation.isRunning();
    }


    public static int getCharWidth(String str, Paint paint) {
        return (int) paint.measureText(str);
    }

    public static float getFontHeight(Paint paint) {
        Paint.FontMetrics fm = paint.getFontMetrics();
        return fm.bottom - fm.top;
    }
}
